require 'test/unit'
require 'models/entity'

class SomeProperty
    attr_accessor :what,:when
end
class ComplexEntity < Entity
    properties :some
end
module MixinModule
    properties :mixin_property
end
class MixinEntity < Entity
    include MixinModule
    properties :entity_property
end

class EntityTest < Test::Unit::TestCase
    def setup
        @entity = Entity.new
    end

    def test_can_set_properties
        @entity.name = "Name"
        assert_equal("Name",@entity.name)
    end
    def test_only_save_properties
        class << @entity
            attr_accessor :bogus
        end
        @entity.bogus = "bogus"

        dump = YAML::dump(@entity)
        @entity = YAML::load(dump)

        assert_nil(@entity.instance_variable_get("@bogus"))
    end
    def test_can_serialize
        require 'yaml'
        @entity.name = "a name"
        @entity.oid = 1
        @entity.description = "a description"

        dump = YAML::dump(@entity)
        undump = YAML::load(dump)

        assert_equal(undump.name,@entity.name)
        assert_equal(undump.oid,@entity.oid)
        assert_equal(undump.description,@entity.description)
        assert_equal(Entity,undump.class)
    end
    def test_comparable
        first = Entity.new
        first.oid = 1
        second = Entity.new
        second.oid = 2
        third = Entity.new
        third.oid = 3

        assert_equal([second,first].sort,[first,second])
        assert(second > first)
        assert(second.between?(first,third))
    end
    def test_nameable
        @entity.name = "Name"
        assert(@entity.named?('name'))
        assert(@entity.named?('nam'))
        assert(! @entity.named?('named'))
    end
    def test_nameable_with_complex_name
        @entity.name = "My Name"
        assert(@entity.named?('My'))
        assert(@entity.named?('name'))
        assert(! @entity.named?('Not My Name'))
    end
    def test_can_clone
        entity = Entity.new
        entity.oid = 1
        entity.name = 'Original'

        cp = entity.clone
        assert_not_equal(entity.oid,cp.oid)

        cp.oid = 88
        assert_not_equal(entity.oid,cp.oid)
    end
    def test_can_clone_complex
        entity = ComplexEntity.new
        entity.oid = 1
        prop = SomeProperty.new
        prop.what = 'Action'; prop.when = Time.now
        entity.some = prop

        cp = entity.clone
        assert_not_equal(entity.oid,cp.oid)

        cp.oid = 88
        assert_not_equal(entity.oid,cp.oid)

        assert_equal(entity.some.when,cp.some.when)
        cp.some.when = Time.now + 60
        assert_not_equal(entity.some.when,cp.some.when)
    end

    def test_can_compose_with_props
        require 'yaml'
        entity = MixinEntity.new

        assert_respond_to(entity,:entity_property)
        assert_respond_to(entity,:mixin_property)

        dump = YAML::dump(entity)
        undump = YAML::load(dump)

        assert_respond_to(undump,:entity_property)
        assert_respond_to(undump,:mixin_property)
    end
end
